「 struct 」から「 抽象データ型(ADT) への移行は、設計思想の根本的な転換です。一方で、 struct はしばしば変数の受動的な集まりですが、ADTは自身の状態を カプセル化を通じて管理する能動的なエンティティです。
1. 設計の意図
C++では、 class キーワードは データ抽象へのコミットを示します。この戦略は、 インターフェース (ユーザーが行えること)と 実装 (データの格納方法)を分離します。内部変数を保護することで、プログラマはオブジェクトが自らの内部整合性を維持することを保証します。
2. 技術的なニュアンス
技術的には、 struct と class の間の唯一の違いは デフォルトのアクセスレベルです。 struct のメンバーは public デフォルトで、オープンなデータ保持者としての役割を反映しています。一方、 class のメンバーは private デフォルトで、管理対象のエンティティとしての役割を反映しています。
$$\text{ADT} = \text{データ} + \text{操作}$$
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is the primary technical difference between a 'struct' and a 'class' in C++?
Structs cannot have member functions.
Classes are stored on the heap while structs are on the stack.
The default access level (public for struct, private for class).
Only classes support inheritance.
✅ Correct!
Correct! It is purely a matter of default access levels to facilitate different design intents.❌ Incorrect
Both can have functions and inheritance; the difference lies in default access permissions.QUESTION 2
What is the goal of 'Data Abstraction'?
To make the code run faster by removing data types.
To separate a type's interface from its implementation.
To allow variables to hold multiple types at once.
To prevent the use of pointers in a class.
✅ Correct!
Yes! Abstraction lets users interact with 'what it does' without worrying about 'how it works'.❌ Incorrect
Abstraction is about the logical separation of interface and implementation detail.QUESTION 3
If a class defines an operation 'combine()', who is responsible for maintaining internal consistency?
The user calling the function.
The operating system.
The class itself via its member functions.
The C++ compiler's garbage collector.
✅ Correct!
Exactly. An ADT manages its own state to ensure internal data remains logical.❌ Incorrect
In an ADT, the class encapsulates the logic to ensure data integrity.QUESTION 4
Why would the initialization 'Sales_data item = "9-999";' fail if it requires two conversions?
C++ allows zero implicit conversions.
C++ allows only one implicit user-defined conversion at a time.
Strings cannot be converted to objects.
Implicit conversions are only allowed for numeric types.
✅ Correct!
Correct. Converting char* to string and then string to Sales_data is one step too many for the compiler.❌ Incorrect
The compiler limits implicit user-defined chains to a single step to prevent ambiguity.QUESTION 5
In the provided code snippet, why is 'my_mem' accessible in main()?
Because it was declared in a struct and is public by default.
Because main() is a friend of struct A.
Because it is a static member.
Because all strings are globally accessible.
✅ Correct!
Indeed. Struct members default to public, allowing external access.❌ Incorrect
Check the default access level of a struct—it's public!Module Implementation Task: The Employee ADT
Applying Encapsulation and Static Members
You are tasked with creating a robust Employee management class. To ensure every employee has a unique identifier, you must use a shared counter that increments with every new instance. This demonstrates encapsulation and class-wide state management.
Q
[Writing Task] Exercise 13.18: Define an Employee class that contains an employee name and a unique employee identifier. Give the class a default constructor and a constructor that takes a string. Each should generate a unique ID. (Min 50 words code/explanation)
Solution:
To implement this, we define a static member `sn` to keep track of the next available ID. cpp class Employee { public: Employee() : id(sn++) { } Employee(const std::string& s) : name(s), id(sn++) { } private: std::string name; int id; static int sn; }; int Employee::sn = 0; // Initialize outside class This design ensures that the unique ID generation is handled internally by the class (encapsulation), and the shared state is maintained across all instances via the static member.
To implement this, we define a static member `sn` to keep track of the next available ID. cpp class Employee { public: Employee() : id(sn++) { } Employee(const std::string& s) : name(s), id(sn++) { } private: std::string name; int id; static int sn; }; int Employee::sn = 0; // Initialize outside class This design ensures that the unique ID generation is handled internally by the class (encapsulation), and the shared state is maintained across all instances via the static member.
Q
Explain why the initialization 'Sales_data item = {"978-0590353403", 25, 15.99};' would fail if any member of Sales_data were made private.
Solution:
This is aggregate initialization. It relies on the class being an aggregate, which requires all data members to be public and for there to be no user-defined constructors. Once you introduce the 'private' keyword for encapsulation, the class is no longer an aggregate, and you must instead provide a constructor that matches the provided argument list to initialize the object.
This is aggregate initialization. It relies on the class being an aggregate, which requires all data members to be public and for there to be no user-defined constructors. Once you introduce the 'private' keyword for encapsulation, the class is no longer an aggregate, and you must instead provide a constructor that matches the provided argument list to initialize the object.